"""统一申请列表资源。

支持多申请类型聚合：
 - LeaveApplication (请假/加班)
 - PurchaseApplication (采购)

查询参数：
 - applicant_id: 过滤申请人
 - status: 过滤状态
 - kind: 单一类型过滤 (leave / purchase)
 - apply_type: 仅针对 leave 类型的细分过滤 (leave/overtime)

返回统一结构列表，每条包含公共字段 + 类型特定字段。"""
from flask import request
from flask_restful import Resource
from ..models import LeaveApplication, PurchaseApplication
from ..utils.helpers import success_response, handle_errors


def _leave_entry(obj: LeaveApplication):
    d = obj.to_dict()
    return {
        'id': d['id'],
        'kind': 'leave',
        'applicant_id': d['applicant_id'],
        'applicant_name': d['applicant_name'],
        'status': d['status'],
        'project_id': d['project_id'],
        'process_instance_id': d['process_instance_id'],
        'created_at': d['created_at'],
        'updated_at': d['updated_at'],
        # 细分字段
        'apply_type': d.get('apply_type'),
        'leave_type': d.get('leave_type'),
        'leave_hours': d.get('leave_hours'),
        'leave_days': d.get('leave_days'),
        'start_date': d.get('start_date'),
        'end_date': d.get('end_date'),
        'reason': d.get('reason')
    }


def _purchase_entry(obj: PurchaseApplication):
    d = obj.to_dict()
    return {
        'id': d['id'],
        'kind': 'purchase',
        'applicant_id': d['applicant_id'],
        'applicant_name': d['applicant_name'],
        'status': d['status'],
        'project_id': d['project_id'],
        'process_instance_id': d['process_instance_id'],
        'created_at': d['created_at'],
        'updated_at': d['updated_at'],
        # 类型特定字段
        'purchase_amount': d.get('purchase_amount'),
        'items': d.get('items')
    }


class ApplicationListResource(Resource):
    """统一的申请列表（支持请假/加班 + 采购）。

    新增分页参数：
      - page: 第几页 (>=1)，默认 1
      - page_size: 每页数量 (1-200)，默认 20
    返回结构：
      {
        "items": [...],
        "total": <总记录数>,
        "page": <当前页>,
        "page_size": <每页大小>,
        "pages": <总页数>
      }
    """

    @handle_errors
    def get(self):
        applicant_id = request.args.get('applicant_id')
        apply_type = request.args.get('apply_type')  # 仅针对 leave 类型
        status = request.args.get('status')
        kind = request.args.get('kind')  # 'leave' / 'purchase'
        # 分页参数
        try:
            page = int(request.args.get('page', '1'))
        except ValueError:
            page = 1
        try:
            page_size = int(request.args.get('page_size', '20'))
        except ValueError:
            page_size = 20
        if page < 1:
            page = 1
        if page_size < 1:
            page_size = 1
        if page_size > 200:
            page_size = 200

        results = []

        # leave 类型
        if kind in (None, 'leave'):
            ql = LeaveApplication.query
            if applicant_id:
                ql = ql.filter_by(applicant_id=applicant_id)
            if apply_type:
                ql = ql.filter_by(apply_type=apply_type)
            if status:
                ql = ql.filter_by(status=status)
            leave_apps = ql.all()
            results.extend(_leave_entry(o) for o in leave_apps)

        # purchase 类型
        if kind in (None, 'purchase'):
            qp = PurchaseApplication.query
            if applicant_id:
                qp = qp.filter_by(applicant_id=applicant_id)
            if status:
                qp = qp.filter_by(status=status)
            purchase_apps = qp.all()
            results.extend(_purchase_entry(o) for o in purchase_apps)

        # 按创建时间倒序（若缺失则放后）
        results.sort(key=lambda r: (r.get('created_at') is not None, r.get('created_at')), reverse=True)

        total = len(results)
        start_idx = (page - 1) * page_size
        end_idx = start_idx + page_size
        page_items = results[start_idx:end_idx]
        pages = (total + page_size - 1) // page_size if page_size else 1

        payload = {
            'items': page_items,
            'total': total,
            'page': page,
            'page_size': page_size,
            'pages': pages
        }
        return success_response(payload, '获取统一申请列表成功')
